package com.fight.strive.sys.modules.mybatis;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fight.strive.sys.modules.common.CondRule;
import com.fight.strive.sys.modules.common.PageR;
import com.fight.strive.sys.modules.exception.StriveException;
import com.fight.strive.sys.utils.CollectionUtils;
import com.fight.strive.sys.utils.ObjectUtils;
import com.fight.strive.sys.utils.StringUtils;

import java.util.List;
import java.util.Map;


public class MyBatisPlusUtils {

    /**
     * 构建条件查询, properties 属性忽略
     */
    public static <T> void buildAndQuery(QueryWrapper<T> queryWrapper,
                                         Map<String, Object> condition,
                                         String... ignoreProperties) {

        if (ObjectUtils.notNull(condition)) {
            condition.forEach((k, v) -> {
                if (!CollectionUtils.contains(ignoreProperties, k)) {
                    if (v instanceof String) {
                        String val = (String) v;
                        queryWrapper.like(
                                StringUtils.isNotBlank(val),
                                StringUtils.camelCase2UnderLine(k), val);
                    } else {
                        if (ObjectUtils.notNull(v)) {
                            queryWrapper.eq(
                                    StringUtils.camelCase2UnderLine(k), v);
                        }
                    }
                }
            });
        }
    }

    /**
     * 根据前端传回来的规则构造条件
     */
    public static <T> void buildRuleQuery(QueryWrapper<T> queryWrapper, PageR<T> page) {
        Map<String, Object> cond = page.getCond();
        List<CondRule> rule = page.getRule();
        buildRuleQuery(queryWrapper, cond, rule);
    }

    /**
     * 递归解析条件规则
     */
    private static <T> void buildRuleQuery(QueryWrapper<T> queryWrapper,
                                           Map<String, Object> cond, List<CondRule> rule) {
        if (CollectionUtils.isNotEmpty(rule)) {
            // 临时条件构造器
            QueryWrapper<T> tempQueryWrapper;
            for (CondRule r : rule) {
                if (StringUtils.equalsIgnoreCase(
                        r.getBlock(), "Y")) {
                    if (StringUtils.equalsIgnoreCase(
                            r.getOperator(), "or")) {
                        queryWrapper.or(qw -> buildRuleQuery(qw, cond, r.getBlockRule()));
                    } else {
                        queryWrapper.and(qw -> buildRuleQuery(qw, cond, r.getBlockRule()));
                    }
                } else {
                    String val = String.valueOf(cond.get(r.getName()) == null ? "" : cond.get(r.getName()));
                    if (StringUtils.isNotBlank(val)) {
                        if (StringUtils.equalsIgnoreCase(
                                r.getName(), "keywords")) {
                            if (CollectionUtils.isNotEmpty(r.getFields())) {
                                if (StringUtils.equalsIgnoreCase(
                                        r.getOperator(), "or")) {
                                    queryWrapper.or(qw -> {
                                        for (String field : r.getFields()) {
                                            qw.or().like(StringUtils.camelCase2UnderLine(field), val);
                                        }
                                    });
                                } else {
                                    queryWrapper.and(qw -> {
                                        for (String field : r.getFields()) {
                                            qw.or().like(StringUtils.camelCase2UnderLine(field), val);
                                        }
                                    });
                                }
                            }
                        } else {
                            if (StringUtils.equalsIgnoreCase(
                                    r.getOperator(), "or")) {
                                tempQueryWrapper = queryWrapper.or();
                            } else {
                                tempQueryWrapper = queryWrapper;
                            }
                            if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), "=")) {
                                tempQueryWrapper.eq(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            } else if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), "like")) {
                                tempQueryWrapper.like(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            } else if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), "l_like")) {
                                tempQueryWrapper.likeLeft(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            } else if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), "r_like")) {
                                tempQueryWrapper.likeRight(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            } else if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), ">")) {
                                tempQueryWrapper.gt(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            } else if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), ">=")) {
                                tempQueryWrapper.ge(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            } else if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), "<")) {
                                tempQueryWrapper.lt(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            } else if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), "<=")) {
                                tempQueryWrapper.le(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            } else if (StringUtils.equalsIgnoreCase(
                                    r.getQuery(), "<>")) {
                                tempQueryWrapper.ne(StringUtils
                                        .camelCase2UnderLine(r.getName()), val);
                            }
                        }
                    }
                }
            }
        }
    }

    /**
     * 检查条件是否符合
     */
    public static <T> void checkConditionValue(Map<String, Object> cond, String... props) {
        if (ObjectUtils.notNull(props) && props.length > 0) {
            if (ObjectUtils.isNull(cond)) {
                throw new StriveException("需要查询条件");
            }
            for (String prop : props) {
                Object v = cond.get(prop);
                if (ObjectUtils.isNull(v)) {
                    throw new StriveException(prop.concat("不能为空"));
                } else if (v instanceof String) {
                    String val = (String) v;
                    if (StringUtils.isBlank(val)) {
                        throw new StriveException(prop.concat("不能为空"));
                    }
                }
            }
        }
    }
}
